/*
 * IndexedDictionary.java
 *
 * Copyright(c) 2010
 * Michael Kroez
 * kroez@studiorutton.de
 *
 * All rights reserved.
 *
 * $Id$
 * 
 */

package de.studiorutton.gerengdic.indexeddictionary;

import java.util.ArrayList;

import android.util.Log;

import de.studiorutton.access.FileAccessException;
import de.studiorutton.gerengdic.Prefs;
import de.studiorutton.gerengdic.databaseaccess.ContentAccess;
import de.studiorutton.gerengdic.databaseaccess.DatabaseAccess;
import de.studiorutton.gerengdic.databaseaccess.DatabaseAccessException;
import de.studiorutton.gerengdic.databaseaccess.LanguageAccess;
import de.studiorutton.gerengdic.databaseaccess.LanguageAccess.IndexPositionRange;
import de.studiorutton.gerengdic.databaseaccess.LanguageAccess.IndexPositionAccess.IndexAll;
import de.studiorutton.gerengdic.databaseaccess.IRecordListener;
import de.studiorutton.gerengdic.history.History;
import de.studiorutton.gerengdic.history.HistoryProvider;
import de.studiorutton.gerengdic.history.IndexedDictionaryCommand;
import de.studiorutton.gerengdic.library.LibraryDatabase;
import de.studiorutton.tre.AMatchResult;

public class IndexedDictionary {
	private final static String TAG = "learningwords";
	private static IndexedDictionary INSTANCE = null;
	
	private String searchString = "";
	private String lastSearchString = "";
	private String autocompleteSearchString = "";
	private IndexedDictionaryWorker idw;

	private IndexedDictionaryListenerProxy idlp;
	private AutoCompleteAdapter aca;
	private AutoCompleteHandler ach;
	private IndexedDictionaryAdapter ida;

	private int firstVisibleAutocomplete;
	private int firstVisibleDictionary;

	private boolean isAutoComplete = true;
	private int crrLanguage = ContentAccess.LANGUAGE_LEFT;

	public IndexedDictionary() {
		// Log.d(TAG, "Creating IndexedDictionaryClass");
		idlp = new IndexedDictionaryListenerProxy();
	}
	
	public static IndexedDictionary get() {
		if (INSTANCE == null )
			INSTANCE = new IndexedDictionary();
		return INSTANCE;
	}
	
	public static void release() {
		INSTANCE.terminateSearchThread();
		INSTANCE = null;
	}

	public void setIndexedDictionaryListener(IIndexedDictionaryView idl) {
		idlp.setIndexedDictionaryListener(idl);
	}

	public IndexedDictionary init() throws FileAccessException,
			DatabaseAccessException {
		if (idw == null)
			idw = new IndexedDictionaryWorker(LibraryDatabase.get().getFileLocation(LibraryDatabase.DE_EN_DICT));
		if (aca == null)
			aca = new AutoCompleteAdapter(idlp);
		if (ach == null)
			ach = new AutoCompleteHandler(idlp, aca);
		if (ida == null)
			ida = new IndexedDictionaryAdapter(idlp, this,
					idw.getDatabaseAccess());

		return this;
	}

	public int getFirstVisibleAutocomplete() {
		return firstVisibleAutocomplete;
	}

	public void setFirstVisibleAutocomplete(int firstVisibleAutocomplete) {
		this.firstVisibleAutocomplete = firstVisibleAutocomplete;
	}

	public int getFirstVisibleDictionary() {
		return firstVisibleDictionary;
	}

	public void setFirstVisibleDictionary(int firstVisibleDictionary) {
		this.firstVisibleDictionary = firstVisibleDictionary;
	}

	public String getSearchString() {
		return searchString;
	}

	public void setSearchString(String searchString) {
		lastSearchString = this.searchString;
		this.searchString = searchString;
	}

	public boolean equalsLastSearchString(String searchString) {
		return lastSearchString.equals(searchString);
	}

	public String getAutocompleteSearchString() {
		return autocompleteSearchString;
	}

	public void setAutocompleteSearchString(String searchString) {
		this.autocompleteSearchString = searchString;
	}

	public boolean isAutoComplete() {
		return isAutoComplete;
	}

	public void setIsAutoComplete(boolean isAutoComplete) {
		this.isAutoComplete = isAutoComplete;
	}

	public AutoCompleteAdapter getAutoCompleteAdapter() {
		return aca;
	}

	public IndexedDictionaryAdapter getIndexedDictionaryAdapter() {
		return ida;
	}

	public IndexedDictionaryWorker getIndexedDictionaryWorker() {
		return idw;
	}

	public int getLanguage() {
		return crrLanguage;
	}

	public void setLanguage(int language) {
		this.crrLanguage = language;
		idlp.updateLanguageButton();
	}

	public void createAutoCompleteList() throws DatabaseAccessException {
		// Log.d(TAG, "IndexedDictionary:getAutocompleteList starting.");
		isAutoComplete = true;

		if (autocompleteSearchString.length() <= 2) {
			aca.clear(true);
			idlp.updateSearchList(true);
			return;
		}
		autocompleteSearchString = autocompleteSearchString.trim();
		firstVisibleAutocomplete = 0;
		idw.cancelSearchOperation();
		// Log.d(TAG,
		// "IndexedDictionary:getAutocompleteList: autocompletesearchString = "
		// + autocompleteSearchString + ".");
		boolean aMatchInIndexSearch = Prefs.getInstance()
				.getAMatchInIndexSearch();
//		Log.d(TAG, "createAutoCompleteList: aMatchInIndexSearch = "
//				+ aMatchInIndexSearch);
		idw.searchAutocompleteInfo(ach, autocompleteSearchString, crrLanguage,
				aMatchInIndexSearch);
		idlp.updateSearchList(true);
		// Log.d(TAG, "IndexedDictionary:getAutocompleteList done.");

	}

	public IndexAll retrieveIndexAll(String searchString, int language)
			throws DatabaseAccessException {
//		 Log.d(TAG, "IndexedDictionary:retieveIndexAll: searchString = "
//		 + searchString);
		DatabaseAccess da = idw.getDatabaseAccess();
		ContentAccess ca = da.getContentAccess();
		LanguageAccess la = ca.getLanguageAccess(language);
		IndexPositionRange ipr = la.getSuperIndexAccess().searchSuperIndex(
				searchString);

		final ArrayList<IndexAll> iaList = new ArrayList<IndexAll>();
		IRecordListener rl = new IRecordListener() {
			ArrayList<IndexAll> myIaList = iaList;

			public void newRecord(IndexAll ia, AMatchResult matchResult) {
				myIaList.add(ia);
			}
		};

		la.getIndexPositionAccess().searchIndex(searchString, false, ipr, rl);
		for (IndexAll ia : iaList) {
			if (ia.indexRecord.getKey().equals(searchString))
				return ia;
		}
		return null;
	}

	public void createIndexList(IndexAll ia) {
		// Log.d(TAG, "createIndexList for " + ia.indexRecord.getKey());
		isAutoComplete = false;
		setSearchString(ia.indexRecord.getKey());
		idw.getDatabaseAccess().setLastIndexPositionRecord(
				ia.indexPositionRecord);

		try {
			ida.initialFill();
		} catch (DatabaseAccessException e) {
			idlp.showErrorDialog(e.getLocalizedMessage());
		}
		firstVisibleDictionary = ida.getIndexSearched();
		idlp.updateEditText();
		idlp.updateSearchList(true);
		addHistoryEntry(null);
	}

	public void clear() {
		if (isAutoComplete)
			aca.clear(true);
		else
			ida.clear(true);
	}

	public void terminateSearchThread() {
		if (idw != null)
			idw.stopSearchThread();

	}

	public void addHistoryEntry(String searchString) {
		if (searchString == null)
			searchString = this.searchString;

		int searchWay = IndexedDictionaryCommand.SEARCH_WAY_INDEXED;
		int searchLanguage = crrLanguage;
		HistoryProvider hp = History.get().getHistoryProvider();
		hp.deleteOld(searchWay, searchString, searchLanguage);
		hp.insert(searchWay, searchString, searchLanguage);
	}

}
